package com.jeremyfeinstein.conference;

import android.os.Handler;
import android.os.HandlerThread;
import android.text.TextUtils;
import android.util.Log;
import android.widget.LinearLayout;

import com.intel.webrtc.base.ActionCallback;
import com.intel.webrtc.base.MediaCodec.VideoCodec;
import com.intel.webrtc.base.RemoteScreenStream;
import com.intel.webrtc.base.RemoteStream;
import com.intel.webrtc.base.Stream.VideoRendererInterface;
import com.intel.webrtc.base.WoogeenException;
import com.intel.webrtc.base.WoogeenIllegalArgumentException;
import com.intel.webrtc.base.WoogeenSurfaceRenderer;
import com.intel.webrtc.conference.ConferenceClient;
import com.intel.webrtc.conference.RemoteMixedStream;
import com.intel.webrtc.conference.SubscribeOptions;
import com.jeremyfeinstein.utils.ConfigUtil;
import com.jeremyfeinstein.utils.WoogeenSampleView;

import org.webrtc.RendererCommon;

import java.util.Hashtable;
import java.util.List;

public class ConferenceStreamView {

    private static final String TAG = ConferenceStreamView.class.getSimpleName();

    private LinearLayout mContainer;
    private WoogeenSampleView sampleView;
    private WoogeenSurfaceRenderer surfaceRenderer;
    private VideoRendererInterface streamRenderer;
    private RemoteStream mRemoteStream;
    private ConferenceClient mRoom;
    private HandlerThread workThread;
    private Handler workHandler;
    private boolean mIsAudioClose;

    public ConferenceStreamView(LinearLayout container) {
        setContainer(container);
        setSampleView(new WoogeenSampleView(container.getContext()));
        setSurfaceRenderer(new WoogeenSurfaceRenderer(getSampleView()));
        getContainer().addView(getSampleView());
        setStreamRenderer(getSurfaceRenderer().createVideoRenderer(0, 0, 100,
                100, RendererCommon.ScalingType.SCALE_ASPECT_FIT, false));
        workThread = new HandlerThread("ConferenceStreamView");
        workThread.start();
        workHandler = new Handler(workThread.getLooper());
    }

    public void playRemoteStreamId(String streamId, boolean isAudioOpen) {
        if (mRoom == null) {
            return;
        }
        mIsAudioClose = isAudioOpen;
        List<RemoteStream> rss = mRoom.getRemoteStreams();
        if (TextUtils.isEmpty(streamId)) {
            for (RemoteStream rs : rss) {
                if (rs instanceof RemoteMixedStream
                        || rs instanceof RemoteScreenStream) {
                    playRemoteStream(rs);
                    return;
                }
            }
        } else {
            for (RemoteStream rs : rss) {
                if (streamId.equals(rs.getId())) {
                    playRemoteStream(rs);
                    return;
                }
            }
            playRemoteStreamId("", mIsAudioClose);
        }
    }






    private void subscribeAndPlay(final RemoteStream remoteStream) {
        workHandler.postDelayed(new Runnable() {
            @Override
            public void run() {
                SubscribeOptions option = new SubscribeOptions();
                option.setVideoCodec("0".equals(ConfigUtil.getInstance().getCompressType()) ? VideoCodec.VP8 : VideoCodec.H264);

                if(remoteStream instanceof RemoteMixedStream){
                    RemoteMixedStream mixedStream = (RemoteMixedStream) remoteStream;
                    Hashtable<String, Integer> minResolution = YCHSConferenceClient.getMinResolution(mixedStream);
                    option.setResolution(minResolution.get("width"),
                            minResolution.get("height"));
                    System.out.println("SubscribeOptions:"+option);
                }
                mRoom.subscribe(remoteStream, option,
                        new ActionCallback<RemoteStream>() {
                            @Override
                            public void onSuccess(final RemoteStream arg0) {
                                mContainer.post(new Runnable() {
                                    @Override
                                    public void run() {
                                        try {
											/*if (!(remoteStream instanceof RemoteMixedStream)) {
												remoteStream.disableAudio();
											}*/

                                            //2017/11/23 添加默认关闭非mix流的声音
                                            if(mIsAudioClose){
                                                remoteStream.disableAudio();
                                            }
//											remoteStream.disableAudio();

                                            remoteStream.attach(streamRenderer);
                                            mRemoteStream = remoteStream;
                                            Log.i("ConferenceRoomUI","subscribe success");
                                        } catch (WoogeenIllegalArgumentException e) {
                                            Log.i("ConferenceRoomUI","exception " + e.getMessage());
                                            e.printStackTrace();
                                        }
                                    }
                                });
                            }

                            @Override
                            public void onFailure(WoogeenException arg0) {
                                Log.i("ConferenceRoomUI","subscribe exception " + arg0.getMessage());
                                arg0.printStackTrace();
                            }
                        });
            }
        }, 500);

    }

    public void playRemoteStream(final RemoteStream remoteStream) {
        if (this.getRemoteStream() != null && null != remoteStream) {
            if (this.getRemoteStream().getId().equals(remoteStream.getId())) {
                return;
            }

            mContainer.post(new Runnable() {
                @Override
                public void run() {
                    try {
                        mRemoteStream.detach(streamRenderer);
                    } catch (Exception e1) {
                        e1.printStackTrace();
                    }
                }
            });

            workHandler.postDelayed(new Runnable() {
                @Override
                public void run() {
                    if(mRemoteStream instanceof RemoteMixedStream){
                        Log.d(TAG, "playRemoteStream1: ");
                        subscribeAndPlay(remoteStream);
                    } else if (remoteStream instanceof RemoteMixedStream) {
                        Log.d(TAG, "playRemoteStream2: ");
                        mRoom.unsubscribe(mRemoteStream,
                                new ActionCallback<Void>() {
                                    @Override
                                    public void onFailure(WoogeenException arg0) {

                                    }

                                    @Override
                                    public void onSuccess(Void arg0) {
                                        mContainer.post(new Runnable() {
                                            @Override
                                            public void run() {
                                                mContainer.post(new Runnable() {
                                                    @Override
                                                    public void run() {
                                                        try {
                                                            remoteStream.attach(streamRenderer);
                                                            Log.i("ConferenceRoomUI","attach() line 170");
                                                            mRemoteStream = remoteStream;
                                                        } catch (WoogeenIllegalArgumentException e) {
                                                            e.printStackTrace();
                                                        }
                                                    }
                                                });
                                            }
                                        });
                                    }
                                });
                    }else{
                        Log.d(TAG, "playRemoteStream3: ");
                        mRoom.unsubscribe(mRemoteStream,
                                new ActionCallback<Void>() {
                                    @Override
                                    public void onFailure(WoogeenException arg0) {

                                    }

                                    @Override
                                    public void onSuccess(Void arg0) {
                                        mContainer.post(new Runnable() {
                                            @Override
                                            public void run() {
                                                subscribeAndPlay(remoteStream);
                                            }
                                        });
                                    }
                                });
                    }
                }
            }, 500);
        } else {
            subscribeAndPlay(remoteStream);
        }
    }

    public void stopRemoteStream() {
        mRoom.unsubscribe(getRemoteStream(), new ActionCallback<Void>() {
            @Override
            public void onSuccess(Void arg0) {
                stop();
                Log.i("ConferenceRoomUI", "unsubscribe success ");
            }

            @Override
            public void onFailure(WoogeenException arg0) {
                Log.i("ConferenceRoomUI", "unsubscribe excetion " + arg0.getMessage());
            }
        });
    }

    public void stop() {
        if (this.getRemoteStream() != null) {
            mContainer.post(new Runnable() {
                @Override
                public void run() {
                    try {
                        if(mRemoteStream != null){
                            getRemoteStream().detach(streamRenderer);
                            Log.i("ConferenceRoomUI","detach() line 230");
                        }
                        mRemoteStream = null;
                        Log.i("ConferenceRoomUI", "stop detach success");
                    } catch (WoogeenIllegalArgumentException e) {
                        Log.i("ConferenceRoomUI", "stop detach exception " + e.getMessage());
                        e.printStackTrace();
                    }
                }
            });
        }
        getStreamRenderer().cleanFrame();
    }

    public void stopNotSetNull() {
        if (this.getRemoteStream() != null) {
            mContainer.post(new Runnable() {
                @Override
                public void run() {
                    try {
                        if(mRemoteStream != null){
                            getRemoteStream().detach(streamRenderer);
                            Log.i("ConferenceRoomUI","detach() line 252");
                        }
                        Log.i("ConferenceRoomUI", "stop detach success");
                    } catch (WoogeenIllegalArgumentException e) {
                        Log.i("ConferenceRoomUI", "stop detach exception " + e.getMessage());
                        e.printStackTrace();
                    }
                }
            });
        }
        getStreamRenderer().cleanFrame();
    }

    public void pause() {
        if (this.getRemoteStream() != null) {
            this.getRemoteStream().disableAudio();
            this.getRemoteStream().disableVideo();
        }

    }

    public void resume() {
        if (this.getRemoteStream() != null) {
            this.getRemoteStream().enableAudio();
            this.getRemoteStream().enableVideo();
        }
    }

    public LinearLayout getContainer() {
        return mContainer;
    }

    public void setContainer(LinearLayout container) {
        this.mContainer = container;
    }

    public WoogeenSampleView getSampleView() {
        return sampleView;
    }

    public void setSampleView(WoogeenSampleView sampleView) {
        this.sampleView = sampleView;
    }

    public WoogeenSurfaceRenderer getSurfaceRenderer() {
        return surfaceRenderer;
    }

    public void setSurfaceRenderer(WoogeenSurfaceRenderer surfaceRenderer) {
        this.surfaceRenderer = surfaceRenderer;
    }

    public VideoRendererInterface getStreamRenderer() {
        return streamRenderer;
    }

    public void setStreamRenderer(VideoRendererInterface streamRenderer) {
        this.streamRenderer = streamRenderer;
    }

    public String getRemoteStreamId() {
        if (mRemoteStream != null) {
            return mRemoteStream.getId();
        }
        return null;
    }

    public RemoteStream getRemoteStream() {
        return mRemoteStream;
    }

    public void setRemoteStream(RemoteStream remoteStream) {
        this.mRemoteStream = remoteStream;
    }

    public ConferenceClient getRoom() {
        return mRoom;
    }

    public void setRoom(ConferenceClient mRoom) {
        this.mRoom = mRoom;
    }

}
